home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Utilities / Winter Shell 1.0d2 / Source / Libraries / ClipbboardLib / ClipboardLib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-16  |  5.9 KB  |  234 lines  |  [TEXT/KAHL]

  1. /*    Library for displaying the contents of the clipboard in a window.
  2.  
  3.     93/12/16 aih
  4.     - added task to update clipboard
  5.     - clipboard window's position is saved in prefs
  6.     
  7.     93/11/20 aih
  8.     - instead of moving the clipboard offscreen on suspend events, the
  9.     clipboard is hidden by calling ShowHide, which doesn't change window
  10.     order
  11.     
  12.     93/10/19 aih
  13.     - made some changes...
  14.     
  15.     93/03/16 AIH
  16.     - Added flag to keep text from being activated
  17.     
  18.     93/03/10 AIH
  19.     - The window's minimum and maximum size are set to fix a problem with
  20.     zooming the window
  21.     
  22.     93/03/06 AIH
  23.     - Added read-only flag to text
  24.     - Menu commands are disable if memory is low
  25.     
  26.     92/02/27 AIH
  27.     - Simplified event handling
  28.     
  29.     91/11/14 AIH
  30.     - Fixed prototype mismatch
  31.     
  32.     91/05/29 AIH
  33.     - Got this to work.
  34.     
  35.     91/05/15 Ari Halberstadt (AIH)
  36.     - Created this library */
  37.     
  38. #include <limits.h>
  39. #include <string.h>
  40. #include "ClipboardLib.h"
  41. #include "DrawLib.h"
  42. #include "EventLib.h"
  43. #include "LowMemLib.h"
  44. #include "MemoryLib.h"
  45. #include "PreferencesLib.h"
  46. #include "RectangleLib.h"
  47. #include "ResourceConstantsLib.h"
  48. #include "TextScrollLib.h"
  49. #include "WindowLib.h"
  50.  
  51. static ClipboardHandle gClipboard;
  52.  
  53. /* true if the clipboard is valid */
  54. Boolean ClipboardValid(ClipboardHandle clipboard)
  55. {
  56.     return(HandleValidSize(clipboard, sizeof(ClipboardType)));
  57. }
  58.  
  59. /* task to update clipboard */
  60. static void ClipboardTask(TaskHandle task, void *data)
  61. {
  62.     ClipboardRefresh(data);
  63. }
  64.  
  65. /* create a clipboard window */
  66. ClipboardHandle ClipboardBegin(void)
  67. {
  68.     Rect newRect;                        /* rectangle for new window */
  69.     Rect portRect;                        /* window's port rectangle */
  70.     short scrapCount;                    /* for setting the scrapCount field */
  71.     WindowPtr window = NULL;        /* new window */
  72.     TextScrollHandle scrl = NULL;    /* the new scroll text */
  73.     TaskHandle task = NULL;            /* update task */
  74.     volatile ClipboardHandle clipboard = NULL;
  75.     
  76.     TRY {
  77.     
  78.         /* create the clipboard window */
  79.         clipboard = HandleBeginClear(sizeof(ClipboardType));
  80.         window = WinGet(RLW_CLIPBOARD);
  81.         (**clipboard).window = window;
  82.         
  83.         /* position the window in the lower left corner of the screen */
  84.         WinPortRect(window, &portRect);
  85.         WinNewRect(window, &newRect);
  86.         newRect.top = newRect.bottom - RectHeight(&portRect);
  87.         newRect.right = newRect.left + RectWidth(&portRect);
  88.         WinMove(window, newRect.left, newRect.top);
  89.                     
  90.         /* create the text */
  91.         InsetRect(&portRect, -1, -1);
  92.         scrl = TxScrlBegin(window, &portRect, true, true, false, false,
  93.                     TX_UNSTYLED_KIND, NULL);
  94.         (**clipboard).scrl = scrl;
  95.         TxWrapSet(TxScrlText(scrl), false);
  96.         FrameFlagsSet(TxScrlFrame(scrl),
  97.             FrameFlags(TxScrlFrame(scrl)) | FRAME_KEEP_INACTIVE);
  98.         TxFlagsSet(TxScrlText(scrl),
  99.             TxFlags(TxScrlText(scrl)) | TX_READ_ONLY | TX_IGNORE_CLICK);
  100.         
  101.         /* Set the scrap count to force a clipboard refresh even
  102.             if the scrap hasn't been modified since the application started
  103.             up. This is necessary since GetScrapCount() returns 0, even though
  104.             there may be information in the scrap that we should display
  105.             (0 is the same as what the clipboard's scrapCount field would
  106.             be if we didn't explicitely initialize it here). */
  107.         scrapCount = GetScrapCount() - 1;
  108.         (**clipboard).scrapCount = scrapCount;
  109.         
  110.         /* insert task to update clipboard */
  111.         task = EventPostTaskInsert(ClipboardTask, clipboard);
  112.         (**clipboard).task = task;
  113.         
  114.         ClipboardRefresh(clipboard);
  115.         WinRegister(window, clipboard, ClipboardEventTable());
  116.         WinZoomRestore(window, PrefsFile(), PREFS_CLIPBOARD_POSITION);
  117.         WinShow(window);
  118.     } CATCH {
  119.         ClipboardEnd(clipboard);
  120.     } ENDTRY;
  121.     ensure(ClipboardValid(clipboard));
  122.     return(clipboard);
  123. }
  124.  
  125. /* end use of the clipboard window */
  126. void ClipboardEnd(ClipboardHandle clipboard)
  127. {
  128.     if (clipboard) {
  129.         EventPostTaskDelete((**clipboard).task);
  130.         TxScrlEnd((**clipboard).scrl);
  131.         if ((**clipboard).window)
  132.             WinZoomSave((**clipboard).window, PrefsFile(), PREFS_CLIPBOARD_POSITION);
  133.         WinUnregister((**clipboard).window, clipboard);
  134.         WinEnd((**clipboard).window);
  135.         HandleEnd(clipboard);
  136.         clipboard = NULL;
  137.     }
  138.     ensure(! ClipboardValid(clipboard));
  139. }
  140.  
  141. /* refresh the data displayed in the clipboard window */
  142. void ClipboardRefresh(ClipboardHandle clipboard)
  143. {
  144.     TextHandle text = NULL;
  145.     
  146.     require(! clipboard || ClipboardValid(clipboard));
  147.     if (clipboard && (**clipboard).scrapCount != GetScrapCount()) {
  148.         text = TxScrlText((**clipboard).scrl);
  149.         TxSelectAll(text);
  150.         TxDelete(text);
  151.         TxPaste(text);
  152.         TxSelect(text, 0, 0);
  153.         TxScrlChanged((**clipboard).scrl);
  154.         TxScrlShowSel((**clipboard).scrl);
  155.         (**clipboard).scrapCount = GetScrapCount();
  156.     }
  157.     ensure(! clipboard || (**clipboard).scrapCount == GetScrapCount());
  158. }
  159.  
  160. /* hide clipboard window on suspend events  */
  161. void ClipboardSuspend(void)
  162. {
  163.     if (gClipboard)
  164.         ShowHide((**gClipboard).window, false);
  165. }
  166.  
  167. /* show clipboard window on resume events */
  168. void ClipboardResume(void)
  169. {
  170.     if (gClipboard)
  171.         ShowHide((**gClipboard).window, true);
  172. }
  173.  
  174. /* true if clipboard window has the focus */
  175. static Boolean ClipboardHasFocus(void)
  176. {
  177.     return(gClipboard && WinHasFocus((**gClipboard).window));
  178. }
  179.  
  180. /* adjust the menu */
  181. void ClipboardAdjustMenu(void)
  182. {
  183.     if (ClipboardHasFocus()) {
  184.         MenuCmdEnable(CMD_CLOSE);
  185.         MenuCmdCheck(CMD_CLIPBOARD, true);
  186.     }
  187.     if (! WinModalHasFocus() && MemWarning() < MEM_WARNING_VERY_LOW) {
  188.         MenuCmdEnable(CMD_CLIPBOARD);
  189.         MenuCmdEnable(CMD_EDIT);
  190.     }
  191. }
  192.  
  193. /* show the clipboard */
  194. void ClipboardShow(void)
  195. {
  196.     if (! gClipboard)
  197.         gClipboard = ClipboardBegin();
  198.     WinSelect((**gClipboard).window);
  199. }
  200.  
  201. /* hide the clipboard */
  202. void ClipboardHide(void)
  203. {
  204.     ClipboardEnd(gClipboard);
  205.     gClipboard = NULL;
  206. }
  207.  
  208. /* handle a menu command */
  209. Boolean ClipboardMenu(const MenuPickType *pick)
  210. {
  211.     Boolean handled = false;
  212.     
  213.     switch (pick->cmd) {
  214.     case CMD_CLIPBOARD:
  215.         ClipboardShow();
  216.         handled = true;
  217.         break;
  218.     case CMD_CLOSE:
  219.         if (ClipboardHasFocus()) {
  220.             ClipboardHide();
  221.             handled = true;
  222.         }
  223.         break;
  224.     }
  225.     return(handled);
  226. }
  227.  
  228. /* close the clipboard if there isn't enough memory */
  229. void ClipboardMemoryLow(void)
  230. {
  231.     if (MemWarning() >= MEM_WARNING_VERY_LOW)
  232.         ClipboardHide();
  233. }
  234.